package com.fll.server.web.routes;

import com.fll.common.JsonUtil;
import com.fll.server.ProxyChannelManager;
import com.fll.server.config.ProxyConfig;
import com.fll.server.config.ProxyConfig.Client;
import com.fll.server.metrics.MetricsCollector;
import com.fll.server.web.ApiRoute;
import com.fll.server.web.RequestHandler;
import com.fll.server.web.RequestMiddleware;
import com.fll.server.web.ResponseInfo;
import com.fll.server.web.exception.ContextException;
import com.google.gson.reflect.TypeToken;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.FullHttpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author fanlei
 * @version 1.0
 * @date 2019年01月25日
 */
public class RouteConfig {
    protected static final String AUTH_COOKIE_KEY = "token";
    private static Logger logger = LoggerFactory.getLogger(RouteConfig.class);
    private static String token;

    public RouteConfig() {
    }

    public static void init() {
        ApiRoute.addMiddleware(new RequestMiddleware() {
            public void preRequest(FullHttpRequest request) {
                String cookieHeader = request.headers().get("Cookie");
                boolean authenticated = false;
                String[] authArr;
                if (cookieHeader != null) {
                    String[] cookies = cookieHeader.split(";");
                    authArr = cookies;
                    int len$ = cookies.length;

                    for(int i$ = 0; i$ < len$; ++i$) {
                        String cookie = authArr[i$];
                        String[] cookieArr = cookie.split("=");
                        if ("token".equals(cookieArr[0].trim()) && cookieArr.length == 2 && cookieArr[1].equals(RouteConfig.token)) {
                            authenticated = true;
                        }
                    }
                }

                String auth = request.headers().get("Authorization");
                if (!authenticated && auth != null) {
                    authArr = auth.split(" ");
                    if (authArr.length == 2 && authArr[0].equals(ProxyConfig.getInstance().getConfigAdminUsername()) && authArr[1].equals(ProxyConfig.getInstance().getConfigAdminPassword())) {
                        authenticated = true;
                    }
                }

                if (!request.getUri().equals("/login") && !authenticated) {
                    throw new ContextException(40100);
                } else {
                    RouteConfig.logger.info("handle request for api {}", request.getUri());
                }
            }
        });
        ApiRoute.addRoute("/config/detail", new RequestHandler() {
            public ResponseInfo request(FullHttpRequest request) {
                List<Client> clients = ProxyConfig.getInstance().getClients();
                Iterator i$ = clients.iterator();

                while(i$.hasNext()) {
                    Client client = (Client)i$.next();
                    Channel channel = ProxyChannelManager.getCmdChannel(client.getClientKey());
                    if (channel != null) {
                        client.setStatus(1);
                    } else {
                        client.setStatus(0);
                    }
                }

                return ResponseInfo.build(ProxyConfig.getInstance().getClients());
            }
        });
        ApiRoute.addRoute("/config/update", new RequestHandler() {
            public ResponseInfo request(FullHttpRequest request) {
                byte[] buf = new byte[request.content().readableBytes()];
                request.content().readBytes(buf);
                String config = new String(buf, Charset.forName("UTF-8"));
                List<Client> clients = (List) JsonUtil.json2object(config, new TypeToken<List<Client>>() {
                });
                if (clients == null) {
                    return ResponseInfo.build(40000, "Error json config");
                } else {
                    try {
                        ProxyConfig.getInstance().update(config);
                    } catch (Exception var6) {
                        RouteConfig.logger.error("config update error", var6);
                        return ResponseInfo.build(40000, var6.getMessage());
                    }

                    return ResponseInfo.build(20000, "success");
                }
            }
        });
        ApiRoute.addRoute("/login", new RequestHandler() {
            public ResponseInfo request(FullHttpRequest request) {
                byte[] buf = new byte[request.content().readableBytes()];
                request.content().readBytes(buf);
                String config = new String(buf);
                Map<String, String> loginParams = (Map)JsonUtil.json2object(config, new TypeToken<Map<String, String>>() {
                });
                if (loginParams == null) {
                    return ResponseInfo.build(40000, "Error login info");
                } else {
                    String username = (String)loginParams.get("username");
                    String password = (String)loginParams.get("password");
                    if (username != null && password != null) {
                        if (username.equals(ProxyConfig.getInstance().getConfigAdminUsername()) && password.equals(ProxyConfig.getInstance().getConfigAdminPassword())) {
                            RouteConfig.token = UUID.randomUUID().toString().replace("-", "");
                            return ResponseInfo.build(RouteConfig.token);
                        } else {
                            return ResponseInfo.build(40000, "Error username or password");
                        }
                    } else {
                        return ResponseInfo.build(40000, "Error username or password");
                    }
                }
            }
        });
        ApiRoute.addRoute("/logout", new RequestHandler() {
            public ResponseInfo request(FullHttpRequest request) {
                RouteConfig.token = null;
                return ResponseInfo.build(20000, "success");
            }
        });
        ApiRoute.addRoute("/metrics/get", new RequestHandler() {
            public ResponseInfo request(FullHttpRequest request) {
                return ResponseInfo.build(MetricsCollector.getAllMetrics());
            }
        });
        ApiRoute.addRoute("/metrics/getandreset", new RequestHandler() {
            public ResponseInfo request(FullHttpRequest request) {
                return ResponseInfo.build(MetricsCollector.getAndResetAllMetrics());
            }
        });
    }
}
